/*
 * pattern.cpp
 *
 *  Created on: 2012-12-12
 *      Author: shane
 */

#include "pattern.h"
#include<string>
#include<cmath>
using namespace std;
namespace EME
{
void pattern::push_back(const block& b)
{
	if (b.geo == NULL || b.mat == NULL)
		throw(EME_pattern_runtime_error("Pattern was pushed a NULL pointer",
				3001));
	if (b.geo->xmin < xmin)
		xmin = b.geo->xmin;
	if (b.geo->xmax > xmax)
		xmax = b.geo->xmax;
	if (b.geo->ymin < ymin)
		ymin = b.geo->ymin;
	if (b.geo->ymax > ymax)
		ymax = b.geo->ymax;
	if (b.mat->if_lossy())
		if_lossy = true;
	blocks.push_back(b);
	return;
}
void pattern::insert(const vector<block>::size_type& index, const block& b)
{
	if (index > blocks.size())
		throw(EME_pattern_runtime_error(
				"Pattern was inserted by out-of-range index", 3002));
	if (b.geo->xmin < xmin)
		xmin = b.geo->xmin;
	if (b.geo->xmax > xmax)
		xmax = b.geo->xmax;
	if (b.geo->ymin < ymin)
		ymin = b.geo->ymin;
	if (b.geo->ymax > ymax)
		ymax = b.geo->ymax;
	if (b.mat->if_lossy())
		if_lossy = true;
	blocks.insert(blocks.begin() + index, b);
	return;
}
void pattern::remove(const std::vector<block>::size_type& index)
{
	if (index + 1 > blocks.size())
		throw(EME_pattern_runtime_error(
				"Pattern was called to delete element of out-of-range index",
				3003));
	for (vector<block>::iterator i = blocks.begin() + index;
			i != blocks.end() - 1; ++i)
		*i = *(i + 1);
	blocks.pop_back();
	xmin = 1e10;
	xmax = -1e10;
	ymin = 1e10;
	ymax = -1e10;
	if_lossy = default_mat->if_lossy();
	for (vector<block>::iterator i = blocks.begin(); i != blocks.end(); ++i)
	{
		if ((*i).geo->xmin < xmin)
			xmin = (*i).geo->xmin;
		if ((*i).geo->xmax > xmax)
			xmax = (*i).geo->xmax;
		if ((*i).geo->ymin < ymin)
			ymin = (*i).geo->ymin;
		if ((*i).geo->ymax > ymax)
			ymax = (*i).geo->ymax;
		if ((*i).mat->if_lossy())
			if_lossy = true;
	}
	return;
}
material* pattern::material_fun(double x, double y)
{
	for (vector<block>::reverse_iterator i = blocks.rbegin();
			i != blocks.rend(); ++i)
	{
		if ((*i).geo->inside(geo_point2(x, y)))
			return (*i).mat;
	}
	return default_mat;
}
}

